<?php

namespace app\commands;

use app\services\User;
use yii\console\Controller;
use yii\helpers\ArrayHelper;
//
class SocketController extends Controller
{
    public $socket;
    public $redis;
    const REDIS_KEY = 'pchat_online_list';

    public function actionRun()
    {
        //实例化redis
        $this->redis = \Yii::$app->redis;
        //实例化swoole
        $this->socket = new \swoole_websocket_server('0.0.0.0', 39501);
        $this->socket->on('Start', [$this, 'onStart']);
        $this->socket->on('Open', [$this, 'onOpen']);
        $this->socket->on('Message', [$this, 'onMessage']);
        $this->socket->on('Close', [$this, 'onClose']);
        $this->socket->start();
    }

    public function onStart()
    {
        //清空在线人员列表
        $this->redis->del(self::REDIS_KEY);
        echo 'run successful' . PHP_EOL;
    }

    public function onOpen(\swoole_websocket_server $socket, $request)
    {
        $user = User::findIdentityByAccessToken($request->get['access_token']);
        if (!$user) {
            $socket->push($request->fd, "用户验证失败");
            return false;
        }

        //群聊用户入栈
        $this->redis->hset(self::REDIS_KEY, $request->fd, serialize(ArrayHelper::toArray($user)));

        echo "用户{$request->fd}加入群聊" . PHP_EOL;
        echo "当前在线用户" . PHP_EOL;
        print_r($this->redis->hkeys(self::REDIS_KEY));
        echo PHP_EOL . PHP_EOL;

        $this->push($socket, "用户 {$user->name} 加入群聊", 'notice');
    }

    public function onMessage(\swoole_websocket_server $socket, $frame)
    {
        echo "用户{$frame->fd}: {$frame->data}" . PHP_EOL;

        $user = unserialize($this->redis->hget(self::REDIS_KEY, $frame->fd));

        $this->push($socket, "{$user['realname']}：$frame->data");
    }

    public function onClose(\swoole_websocket_server $socket, $fd)
    {
        $user = unserialize($this->redis->hget(self::REDIS_KEY, $fd));
        $this->push($socket, "用户 {$user['realname']} 退出群聊", 'notice');

        $this->redis->hdel(self::REDIS_KEY, $fd);

        echo "用户{$fd}退出群聊" . PHP_EOL;
        echo "当前在线用户" . PHP_EOL;
        print_r($this->redis->hkeys(self::REDIS_KEY));
        echo PHP_EOL . PHP_EOL;
    }

    private function push($socket, $message, $type = 'message')
    {
        $fd_list = $this->redis->hkeys(self::REDIS_KEY);
        $return = [
            'type' => $type,
            'message' => $message,
            'time' => date('m-d H:i:s')];
        foreach ($fd_list as $fd) {
            $socket->push($fd, json_encode($return, 256));
        }
    }
}